﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

using ZhimeiSoft.CharmManager.DOL;
using ZhimeiSoft.CharmManager.Server.Factory;
using ZhimeiSoft.CharmManager.Server.BLL.Interface;
using ZhimeiSoft.CharmManager.Server.DAL.Interface;

namespace ZhimeiSoft.CharmManager.Server.BLL
{
    public class ReservationBLL : IReservationBLL
    {
        IReservationDAL reservationDAL;
        ICustomerServiceItemDAL customServiceItemDAL;
        ICustomerServiceItemReservationTimeDAL customServiceReservationTimeDAL;
        IToDoListDAL todoListDAL;
        ICustomerDAL customDAL;

        public ReservationBLL()
        {
            reservationDAL = BaseDalFactory.CreateReservationDal();
            customServiceItemDAL = BaseDalFactory.CreateCustomerServiceItemDal();
            customServiceReservationTimeDAL = BaseDalFactory.CreateCustomerServiceItemReservationTimeDal();
            todoListDAL = BaseDalFactory.CreateToDoListDal();
            customDAL = BaseDalFactory.CreateCustomerDal();

        }
        /// <summary>
        /// 获取预约信息
        /// </summary>
        /// <param name="queryYear">查询年</param>
        /// <param name="queryMonth">查询月</param>
        /// <param name="queryDay">查询日</param>
        /// <param name="stateStr">预约状态</param>
        /// <returns></returns>
        public DataSet GetResveration(int queryYear, int queryMonth, int queryDay, string stateStr)
        {
            return reservationDAL.QueryResveration(queryYear, queryMonth, queryDay, stateStr);
        }

        /// <summary>
        /// 根据信息查询预约ＩＤ
        /// </summary>
        /// <param name="reservatioinInfo"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public int QueryResverationID(DBEntityReservation reservatioinInfo)
        {
            return reservationDAL.GetReservationID(reservatioinInfo);
        }
        /// <summary>
        /// 跟据月份查询预约信息
        /// </summary>
        /// <param name="queryYear">查询年</param>
        /// <param name="queryMonth">查询月</param>
        /// <returns></returns>
        public DataSet QueryReservationMonth(int queryYear, int queryMonth, string state)
        {
            return reservationDAL.QueryReservationMonth(queryYear, queryMonth, state);
        }
        /// <summary>
        /// 获取员工预约信息
        /// </summary>
        /// <param name="queryYear">查询年</param>
        /// <param name="queryMonth">查询月</param>
        /// <param name="queryDay">查询日</param>
        /// <param name="employeeID">员工ID</param>
        /// <param name="stateStr">预约状态</param>
        /// <returns></returns>
        public DataSet GetReservationEmployee(int queryYear, int queryMonth, int queryDay, int employeeID, string stateStr)
        {
            return reservationDAL.QueryReservationEmployee(queryYear, queryMonth, queryDay, employeeID, stateStr);
        }
        /// <summary>
        /// 根据预约ID查询对应的服务项目
        /// </summary>
        /// <param name="reservationID"></param>
        /// <returns></returns>
        public DataSet QueryReservationServiceItem(int reservationID)
        {
            return reservationDAL.QueryReservationServiceItem(reservationID);
        }

        /// <summary>
        /// 根据时间和会员查询预约
        /// </summary>
        /// <param name="querYear">年</param>
        /// <param name="queryMonth">月</param>
        /// <param name="queryDay">日</param>
        /// <param name="customID">会员ID</param>
        /// <param name="dsReservation">返回查询结果</param>
        /// <param name="error">错误信息</param>
        /// <returns></returns>
        public DataSet QueryReservationCustom(int queryYear, int queryMonth, int queryDay, int customID)
        {
            return reservationDAL.QueryReservationCustom(queryYear, queryMonth, queryDay, customID);
        }

        public void AddResveration(DBEntityReservation reservatioinInfo, DataSet dsReservationServiceItem)
        {
            reservationDAL.AddResveration(reservatioinInfo, dsReservationServiceItem);
        }

        public void UpdateReservation(DBEntityReservation reservatioinInfo, DataSet dsReservationServiceItem)
        {
            reservationDAL.UpdateReservation(reservatioinInfo, dsReservationServiceItem);
        }

        /// <summary>
        /// 更新预约状态
        /// </summary>
        /// <param name="reservationID"></param>
        /// <param name="customServiceItemID"></param>
        /// <param name="state"></param>
        public void UpdateReservationCustomServiceItemState(int reservationID, int customServiceItemID, int employeeID, string state)
        {
            reservationDAL.UpdateReservationCustomServiceItemState(reservationID, customServiceItemID, employeeID, state);
        }

        /// <summary>
        /// 计算下一次的预约时间
        /// </summary>
        /// <param name="customerServiceItemID">预约的项目ID</param>
        public int ComputerNextReservation(int customerServiceItemID)
        {
            return customServiceItemDAL.QueryComputerNextResveration(customerServiceItemID);
        }
        /// <summary>
        /// 查询会员卡项预约情况
        /// </summary>
        /// <param name="customID">会员ID</param>
        /// <param name="customServiceItemID">会员服务项目ID</param>
        /// <returns></returns>
        public DataSet QeuryReservationCustomServiceItem(int customID, int customServiceItemID)
        {
            return reservationDAL.QeuryReservationCustomServiceItem(customID, customServiceItemID);
        }

        /// <summary>
        /// 查询会员卡预约情况
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public DataSet QueryReservationCustomServiceItemFilter(string filter)
        {
            return reservationDAL.QueryReservationCustomServiceItemFilter(filter);
        }

        /// <summary>
        /// 根据预约ID查询详细项目
        /// </summary>
        /// <param name="reservationID">预约ＩＤ</param>
        /// <returns></returns>
        public DataSet QueryReservationServiceItemDetail(int reservationID)
        {
            return reservationDAL.QueryReservationServiceItemDetail(reservationID);
        }

        /// <summary>
        /// 预约项目调整
        /// </summary>
        /// <param name="ajdustReservationID">当前调整的预约项目ID</param>
        /// <param name="adjustDateTime">预约调整后的时间</param>
        /// <param name="customServiceItemID">要调整的时间</param>
        /// <param name="customID">会员</param>
        public void AdjustReservationCustomServiceItem(int reservationID, DateTime adjustDateTime,
            int customServiceItemID, int customID)
        {
            //获取用户调整时间的预约记录
            DataSet dsReservation = reservationDAL.QueryReservationCustom(adjustDateTime.Year, adjustDateTime.Month,
                adjustDateTime.Day, customID);

            //获取用户详细预约记录
            DataSet dsReservationServiceItem;
            DBEntityReservation reservationInfo = new DBEntityReservation();
            //1、查询是否有主预约记录如果没有那么生成预约
            if (dsReservation.Tables[0].Rows.Count == 0)
            {
                reservationInfo.RESERVATIONTIME = adjustDateTime;
                reservationInfo.CUSTOMERID = customID;
                reservationInfo.RWORKSTARTTIME = adjustDateTime;
                reservationInfo.RSTATE = DBEntityReservation.ENUM_RSTATE.C0N;
                dsReservationServiceItem = reservationDAL.QueryReservationServiceItem(-1);
            }
            else
            {
                reservationInfo = new DBEntityReservation(dsReservation.Tables[0].Rows[0]);
                dsReservationServiceItem = reservationDAL.QueryReservationServiceItem(reservationInfo.RESERVATIONID);
            }
            
            //获取被调整的预约项目
            DataSet dsAdjustReservation = reservationDAL.QueryReservationServiceItem(reservationID);
            DBEntityReservation adjReservationInfo = new DBEntityReservation(dsAdjustReservation.Tables[1].Rows[0]);

            DataRow[] drAdjustRows = dsAdjustReservation.Tables[0].Select(DBEntityReservationServiceItem.FieldName.CUSTOMERSERVICEITEMID + " = " + customServiceItemID.ToString());

            //将预约的项目添加到数据集
            DataRow drNew = dsReservationServiceItem.Tables[0].NewRow();
            object[] obj = new object[dsReservationServiceItem.Tables[0].Columns.Count];
            drAdjustRows[0].ItemArray.CopyTo(obj, 0);
            drNew.ItemArray = obj;
            drNew[DBEntityReservation.FieldName.RESERVATIONID] = reservationInfo.RESERVATIONID;
            dsReservationServiceItem.Tables[0].Rows.Add(drNew);
            
            drAdjustRows[0].Delete();//删除预约项目

            reservationInfo.RMEMO = reservationInfo.RMEMO + "\r\n预约调整，调整时间：" + DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString()
                + " 原来的预约时间：" + adjReservationInfo.RESERVATIONTIME.ToLongDateString() + " " + adjReservationInfo.RESERVATIONTIME.ToLongTimeString() 
                + " 调整项目：" + "[" + drNew[DBEntityServiceItem.FieldName.SERVICEITEMCODE].ToString() + "]" + drNew[DBEntityServiceItem.FieldName.SNAME].ToString() ;
            //2、重新计算时间，重新添加待办事项提醒
            string description = computerReservationWorkTime(ref reservationInfo, dsReservationServiceItem.Tables[0]);

            //更新原来的数据集删除
            reservationDAL.DeleteAdjReservationServiceItemDetail(dsAdjustReservation);

            //3、将预约项目进行调整,并保存。
            reservationDAL.UpdateReservation(reservationInfo, dsReservationServiceItem);
            
            //4、重新生成提醒
            refreshToDoList(reservationInfo, description, adjustDateTime);
            //5、如果被调整项目没有预约项目那么清除预约记录，并且清除提醒
            
            if (dsAdjustReservation.Tables[0].Rows.Count == 0)
            {
                //已经没有预约明细，所以删除预约项目
                reservationDAL.DeleteReservation(reservationID);
            }
            else
            {
                //更新调整时间
                description = computerReservationWorkTime(ref adjReservationInfo, dsAdjustReservation.Tables[0]);
                reservationDAL.UpdateReservation(adjReservationInfo, null);

                DataSet dsAdjReservationToDoList = todoListDAL.GetToDoListReservation(reservationID);
                if (dsAdjReservationToDoList.Tables[0].Rows.Count > 0)
                {
                    DataSet dsAdjToDoList = todoListDAL.GetToDoListForID(Convert.ToInt16(dsAdjReservationToDoList.Tables[0].Rows[0][DBEntityReservationToDoList.FieldName.TODOLISTID]));
                    DBEntityToDoList adjToDoList = new DBEntityToDoList(dsAdjToDoList.Tables[0].Rows[0]);
                    //重新生成提醒并计算最后完成时间
                    string[] decription = adjToDoList.TODODECRIPTION.Split('|');
                    adjToDoList.TODODECRIPTION = description[0] + "|" + description;
                    todoListDAL.UpdateToDoList(adjToDoList);
                }
            }

        }

        /// <summary>
        ///  重新计算预约完成时间
        /// </summary>
        /// <param name="reservationInfo"></param>
        /// <param name="dtCustomReservation"></param>
        /// <returns></returns>
        private string computerReservationWorkTime(ref DBEntityReservation reservationInfo, DataTable dtCustomReservation)
        {
            string serviceItemName = "";
            int minute = 0;
            DataRow[] drRows = dtCustomReservation.Select("", "", DataViewRowState.CurrentRows);
            foreach (DataRow drRow in drRows)
            {
                minute += Convert.ToInt16(drRow[DBEntityServiceItem.FieldName.STIMESPAN]);
                serviceItemName += ((serviceItemName == string.Empty) ? "" : ", ") + "[" + drRow[DBEntityServiceItem.FieldName.SERVICEITEMCODE].ToString() + "]" +
                    drRow[DBEntityServiceItem.FieldName.SNAME].ToString();
            }
            reservationInfo.RWORKSTARTTIME = reservationInfo.RESERVATIONTIME;
            reservationInfo.RWORKENDTIME = reservationInfo.RWORKSTARTTIME.AddMinutes(minute);
            return serviceItemName;
        }
        /// <summary>
        /// 预约调整
        /// </summary>
        /// <param name="entityReservation"></param>
        public void AdjustReservation(DBEntityReservation entityReservation, int reservationEmployeeID)
        {
            DataSet dsReservation = reservationDAL.QueryReservationCustom(entityReservation.RESERVATIONTIME.Year, entityReservation.RESERVATIONTIME.Month,
                entityReservation.RESERVATIONTIME.Day, entityReservation.CUSTOMERID);

            int reservationID = entityReservation.RESERVATIONID;
            if (dsReservation.Tables[0].Rows.Count > 0)
            {
                //存在预约记录，下面进行预约合并
                reservationDAL.UpdateAdjReservationServiceItem(entityReservation.RESERVATIONID,
                    Convert.ToInt16(dsReservation.Tables[0].Rows[0][DBEntityReservation.FieldName.RESERVATIONID]));

                reservationID = Convert.ToInt16(dsReservation.Tables[0].Rows[0][DBEntityReservation.FieldName.RESERVATIONID]);
            }
            else
            {
               //直接更新时间
                reservationDAL.UpdateAdjReservation(entityReservation);
            }
            //更新预约状态
            reservationDAL.UpdateReservationState(reservationID, entityReservation, entityReservation.RESERVATIONTIME);

            if (reservationEmployeeID != -1)
            {
                reservationDAL.UpdateReservationEmployee(entityReservation.RESERVATIONID, reservationEmployeeID);
            }
            //更新预约明细表的时间并且更新主表操作时间
            string decscription = refreshWorkTime(entityReservation);
            refreshToDoList(entityReservation, decscription, entityReservation.RWORKSTARTTIME);

        }
        /// <summary>
        /// 刷新工作时间
        /// </summary>
        /// <param name="reservation"></param>
        private string refreshWorkTime(DBEntityReservation reservationInfo)
        {
            DataSet dsReservationServiceItem = reservationDAL.QueryReservationServiceItem(reservationInfo.RESERVATIONID);
            string description = computerReservationWorkTime(ref reservationInfo, dsReservationServiceItem.Tables[0]);
            reservationDAL.UpdateAdjReservation(reservationInfo);
            return description;

        }
        /// <summary>
        /// 刷新预约项目的提示
        /// </summary>
        /// <param name="reservationInfo"></param>
        public void refershReservationToDoList(DBEntityReservation reservationInfo)
        {
            //更新预约明细表的时间并且更新主表操作时间
            DataSet dsReservationServiceItem = reservationDAL.QueryReservationServiceItem(reservationInfo.RESERVATIONID);
            string description = computerReservationWorkTime(ref reservationInfo, dsReservationServiceItem.Tables[0]);

            refreshToDoList(reservationInfo, description, reservationInfo.RESERVATIONTIME);
        }
        /// <summary>
        /// 刷新待办事项列表
        /// </summary>
        /// <param name="reservation"></param>
        private void refreshToDoList(DBEntityReservation reservationInfo, string description, DateTime adjustDateTime)
        {
            //4、重新生成提醒
            DataSet dsToDoReservation = todoListDAL.GetToDoListReservation(reservationInfo.RESERVATIONID);
            DataSet dsToDoList;
            DBEntityToDoList todoList;
            if (dsToDoReservation.Tables[0].Rows.Count == 0)
            {
                //没有提醒生成提醒记录，并判断时间是否生成提醒
                DBEntityReservationToDoList toDoListReservation = new DBEntityReservationToDoList();
                toDoListReservation.RESERVATIONID = reservationInfo.RESERVATIONID;

                int icompAdjDate = adjustDateTime.Year * 10000 + adjustDateTime.Month * 100 + adjustDateTime.Day;
                int iNowDate = DateTime.Now.Year * 10000 + DateTime.Now.Month * 100 + DateTime.Now.Day + 1;

                if (iNowDate < icompAdjDate)
                {
                    DataSet dsReservationServiceItem = reservationDAL.QueryReservationServiceItemDetail(reservationInfo.RESERVATIONID);
                    if (dsReservationServiceItem.Tables[0].Rows.Count == 0)
                    {
                        throw new Exception("没有查到当前预约的项目。");
                    }
                    DataSet dsCustom = customDAL.QueryCustomID(reservationInfo.CUSTOMERID);
                    DBEntityCustomInfo customInfo = new DBEntityCustomInfo(dsCustom.Tables[0].Rows[0]);
                    description = "今日预约确认 会员：" + customInfo.CNAME + "(" + customInfo.CNICKNAME + ") 预约时间：" + reservationInfo.RESERVATIONTIME.ToLongDateString()
                        + " " + reservationInfo.RESERVATIONTIME.ToLongTimeString() + " 到店 会员电话：" + customInfo.CMOBILEPHONE + " 护理项目：| " + description;

                    todoList = new DBEntityToDoList();

                    //生成任务开始时间
                    DateTime startTime = new DateTime(reservationInfo.RESERVATIONTIME.Ticks);
                    todoList.TODOSTARTTIME = new DateTime(startTime.Year, startTime.Month, startTime.Day, 8, 0, 0);
                    todoList.TODOENDTIME = new DateTime(startTime.Year, startTime.Month, startTime.Day, 23, 59, 59);
                    todoList.TODOSTATE = DBEntityToDoList.ENUM_TODOSTATE.T0N;
                    todoList.TODOMEMO = "此事项由预约生成";
                    todoList.TODODECRIPTION = description;
                    todoList.EMPLOYEEID = Convert.ToInt16(dsReservationServiceItem.Tables[0].Rows[0][DBEntityReservationServiceItem.FieldName.EMPLOYEEID]);
                    todoListDAL.InsertResverationToDoList(todoList, toDoListReservation);
                }
            }
            else
            {
                dsToDoList = todoListDAL.QueryTodoList(DBEntityToDoList.FieldName.TODOLISTID + " = " +
                    dsToDoReservation.Tables[0].Rows[0][DBEntityReservationToDoList.FieldName.TODOLISTID].ToString());
                //有提醒记录
                todoList = new DBEntityToDoList(dsToDoList.Tables[0].Rows[0]);
                if (todoList.TODODECRIPTION.IndexOf(description) < 0)
                {
                    string[] sDecription = todoList.TODODECRIPTION.Split('|');
                    todoList.TODODECRIPTION = sDecription[0] + "|" + description;
                    todoListDAL.UpdateToDoList(todoList);//更新
                }
            }
        }

        /// <summary>
        /// 更新过期的预约状态
        /// </summary>
        /// <param name="error">错误信息</param>
        /// <returns></returns>
        public void CheckAllReservationState()
        {
            reservationDAL.CheckAllReservationState();
        }
    }
}
